/*******************************************************************************
 * Copyright (c) 2011 Jovansonlee B. Cesar.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the GNU Public License v2.0
 * which accompanies this distribution, and is available at
 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
 * 
 * Contributors:
 *     Jovansonlee B. Cesar - initial API and implementation
 ******************************************************************************/
package com.ivanceras.client.widgets;

import java.util.ArrayList;
import java.util.List;

import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiField;
import com.google.gwt.uibinder.client.UiHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HTMLPanel;
import com.google.gwt.user.client.ui.Widget;
import com.ivanceras.shared.bo.Ad_field;
import com.ivanceras.shared.bo.Ad_tab;
import com.ivanceras.shared.bo.Ad_table;
import com.ivanceras.shared.db.DAO;
import com.ivanceras.shared.db.Filter;

public class AdTabUi extends Composite {

	private static AdTabUiUiBinder uiBinder = GWT.create(AdTabUiUiBinder.class);

	interface AdTabUiUiBinder extends UiBinder<Widget, AdTabUi> {
	}

	@UiField HTMLPanel contentPanel;
	@UiField Button next;
	@UiField Button prev;
	@UiField HTML recordSummary;

	Ad_field[] adFieldList = null;
	List<AdFieldUi> adFieldUiList = new ArrayList<AdFieldUi>();
	List<SingleRecordUi> singleRecordUiList = new ArrayList<SingleRecordUi>();
	DAO focusedDAO = null;
	DAO[] daoList = null;
	
	TabController controller = null;

	Ad_tab adtab = null;
	//public FilterManager filterManager;
	public WindowController windowController;
	private Boolean singleView;
	
	public AdTabUi(Ad_tab tab, Boolean singleRowView) {
		initWidget(uiBinder.createAndBindUi(this));
		this.adtab = tab;
		Ad_table table = tab.getAd_table();
		this.singleView = singleRowView;
		controller = new TabController(this, null);
		if(singleRowView){
			singleView(tab);
		}else{
			listView(tab);
		}
	}

	private void singleView(Ad_tab tab){
		adFieldList = tab.getAd_fieldList();
		for(Ad_field f : adFieldList){
			AdFieldUi field = new AdFieldUi(f);
			adFieldUiList.add(field);
			contentPanel.add(field);
		}
	}
	
	private void listView(final Ad_tab tab){
		for(int i = 0; i < controller.itemPerPage; i++){
			SingleRecordUi row = new SingleRecordUi(tab, 
					new ClickHandler(){
						
						@Override
						public void onClick(ClickEvent event){
							singleView = true;
							adFieldUiList.clear();
							contentPanel.clear();
							singleView(tab);
							displayDefault();
						}
					});
			contentPanel.add(row);
			singleRecordUiList.add(row);
		}
	}
	
	public Ad_tab getAd_tab(){
		return this.adtab;
	}

	public void setRecord(final int recordIndex){
		if(recordIndex < 0){
			try {
				throw new Exception("Record index should not be less than zero");
			} catch (Exception e) {
				e.printStackTrace();
			}
			return;
		}
		int recordLength = daoList != null ? daoList.length : 0;
		if(recordIndex >= recordLength){
			System.out.println("Request next page from the server: recordIndex: "+recordIndex);
			controller.requestNextPage(windowController.getFilter(this), new AsyncCallback<DAO[]>() {

				@Override
				public void onSuccess(DAO[] result) {
					daoList = result;
//					checkSetButtonStates();
					setRecordNoCheck(recordIndex);
				}

				@Override
				public void onFailure(Throwable caught) {
					System.err.println("Unable to load requested next page...");
					caught.printStackTrace();
				}
			});
		}
		else{
			setRecordNoCheck(recordIndex);
		}
	}

	public void setRecordNoCheck(int recordIndex){
		System.out.println("record index: "+recordIndex);
		controller.setCurrentRecordIndex(recordIndex);
		if(daoList != null){
			int totalDaoRecordsLoaded = daoList.length;
			System.out.println("displaying: "+(recordIndex+1)+" of "+totalDaoRecordsLoaded);
			recordSummary.setText((recordIndex+1)+" of "+totalDaoRecordsLoaded+" total");
			int daoLength = daoList.length;
			int currentRecordIndex = controller.getCurrentRecordIndex();
			if(currentRecordIndex < daoLength){
				DAO dao = daoList[currentRecordIndex];
				setFocusedDAO(dao);
				if(singleView){
					displayDaoContent(dao);
				}else{
					listDao(daoList, controller.getCurrentRecordIndex());
			}
			}
		}

	}

	private void listDao(DAO[] currentDaoList, Integer currentRecordIndex) {
		clearRecordViewers();
		int itemPerPage = controller.itemPerPage;
		int showPage = currentRecordIndex / itemPerPage;
		int pageRem = currentRecordIndex % itemPerPage;
		int offsetPage = showPage * itemPerPage;
		System.out.println("offset: "+offsetPage);
		int daoLength = currentDaoList.length;
		int daoRem = daoLength % itemPerPage;
		int displayLength =  daoRem + ((daoLength / itemPerPage) > 0 ? 1 : 0) * itemPerPage;
		System.out.println("displayLength: "+displayLength);
		for(int i = 0; i < displayLength; i++){
			DAO dao = currentDaoList[offsetPage+i];
			SingleRecordUi record = singleRecordUiList.get(i);
			record.setDao(dao);
			SingleRecordUi selectedRecord = singleRecordUiList.get(pageRem);
			if( ( offsetPage + i )== currentRecordIndex){
				selectedRecord.setSelected(true);
			}else{
				record.setSelected(false);
			}
		}
	}
	
	private void clearRecordViewers(){
		int itemPerPage = controller.itemPerPage;
		for(int i = 0; i < itemPerPage; i++){
			SingleRecordUi record = singleRecordUiList.get(i);
			record.clear();
		}
		
	}
	
	public void nextRecord(){
		int currentRecord = controller.getCurrentRecordIndex();
		currentRecord++;
		setRecord(currentRecord);
	}

	public void previousRecord(){
		int currentRecord = controller.getCurrentRecordIndex();
		currentRecord--;
		setRecord(currentRecord);
	}

	public void displayDefault(){
		setRecord(controller.getCurrentRecordIndex());
	}

	@UiHandler("next")
	void onNext(ClickEvent e){
		System.out.println("Next record");
		nextRecord();
	}

	@UiHandler("prev")
	void onPrev(ClickEvent e){
		System.out.println("previous record");
		previousRecord();
	}

	public void setFocusedDAO(DAO dao){
		focusedDAO = dao;
	}
	
	private void displayDaoContent(DAO dao){
		for(int i = 0; i < adFieldList.length; i++){
			Ad_field field = adFieldList[i];
			String columnName = field.getAd_column().getColumnname().toLowerCase();
			Object value = dao.get_Value(columnName);
			adFieldUiList.get(i).setValue(value);
		}

	}

	public Object getFieldValue(String columnName){
		return focusedDAO.get_Value(columnName.toLowerCase());
	}

	
//	private Filter getFilter(){
//		return this.filterManager.getFilter(this);
//	}
	
//	private String getHash(){
//		Filter filter = getFilter();
//		AdTabUi tabUi = filterManager.getParentTabUi();
//		
//		String tableName = "";
//		if(tabUi != null){
//			tableName = tabUi.getAd_tab().getAd_table().getTablename();
//			tableName = tableName.toLowerCase();
//			System.err.println("parent tabui: "+tableName);
//		}
//		String filterValue = "";
//		if(filter != null){
//			if(filter.value != null){
//				filterValue = filter.value.toString();
//			}
//		}
//		String hash = tableName+filterValue;
//		System.out.println("gethash: "+hash);
//		return hash;
//	}
	

//	public void setFilterManager(FilterManager fm) {
//		this.filterManager = fm;
//	}
	
	public void setWindowController(WindowController wc){
		this.windowController = wc;
	}
	

}
